﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Data;
using System.Collections;
using System.Reflection;
using System.Drawing;
using System.Configuration;

namespace Liang.Util.Rest
{
    /// <summary>
    /// REST 常量
    /// </summary>
    public static class RestConst
    {
        public const string ContentType_json = "application/json;charset=UTF-8";
        public const string ContentType_text = "text/html";

        /// <summary>
        /// 请求方法
        /// </summary>
        public enum RequestMethod
        {
            GET,
            POST,
            PUT,
            DELETE
        }
    }

    /// <summary>
    /// rest工具类
    /// </summary>
    public class HttpClients
    {
        //public static readonly string rest_url = ConfigurationManager.AppSettings["restUrl"];
        public static readonly string server_url = ConfigurationManager.AppSettings["serverUrl"];

        /// <summary>
        /// 判断服务器连接
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static bool httpValidate()
        {
            HttpWebRequest req = null;
            HttpWebResponse res = null;
            bool CanCn = true;   //设成可以连接； 
            try
            {
                req = (HttpWebRequest)WebRequest.Create(server_url);
                res = (HttpWebResponse)req.GetResponse();
            }
            catch (Exception)
            {
                CanCn = false;   //无法连接 
            }
            finally
            {
                if (res != null)
                {
                    res.Close();
                }
            }
            return CanCn;
        }

        public static string doGetMethod(string methodUrl)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "get";
            request.ContentType = RestConst.ContentType_text;
            HttpWebResponse response = null;

            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                //response = (HttpWebResponse)e.Response;
                throw e;
            }

            return getResponseString(response);
        }

        // REST @GET 方法，根据泛型自动转换成实体，支持List<T>
        public static T doGetMethodToObj<T>(string methodUrl)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "get";
            request.ContentType = RestConst.ContentType_json;
            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                //response = (HttpWebResponse)e.Response;
                //MessageBox.Show(e.Message + " - " + getRestErrorMessage(response));
                //return default(T);
                throw e;
            }
            string json = getResponseString(response);

            json = json.Replace("@", "");
            return Json.JsonTool.JsonDeserialize<T>(json);
        }


        // REST @GET 方法，根据泛型自动转换成实体，支持List<T>
        public static List<T> doGetMethodToObjs<T>(string methodUrl)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "get";
            request.ContentType = RestConst.ContentType_json;
            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                //response = (HttpWebResponse)e.Response;
                //MessageBox.Show(e.Message + " - " + getRestErrorMessage(response));
                //return null;
                throw e;
            }
            string json = getResponseString(response);

            json = json.Replace("@", "");
            return Json.JsonTool.JSONStringToList<T>(json);
        }


        /// <summary>
        /// 发送一个请求，获取操作成功或失败（结果以字符串形式返回，具体内容根据双方前后端协商）
        /// </summary>
        /// <param name="jsonData"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public static string doGetRequest(string methodUrl)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "get";
            request.ContentType = RestConst.ContentType_json;
            HttpWebResponse response = null;

            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                //response = (HttpWebResponse)e.Response;
                //MessageBox.Show(e.Message);
                //return string.Empty;
                throw e;
            }

            return getResponseString(response);
        }

        // 将 HttpWebResponse 返回结果转换成 string
        private static string getResponseString(HttpWebResponse response)
        {
            string json = null;
            using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("UTF-8")))
            {
                json = reader.ReadToEnd();

            }
            return json;
        }

        /// <summary>
        /// 将 HttpWebResponse 返回结果转换成 byte[]
        /// </summary>
        /// <param name="methodUrl"></param>
        /// <returns></returns>
        public static byte[] getResponseByte(string methodUrl)
        {

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "get";
            request.ContentType = RestConst.ContentType_json;
            HttpWebResponse response = null;
            byte[] buffer = new byte[64 * 1024];
            try
            {
                response = (HttpWebResponse)request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                MemoryStream stmMemory = new MemoryStream();

                int i;
                while ((i = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    stmMemory.Write(buffer, 0, i);
                }
                byte[] arraryByte = stmMemory.ToArray();
                stmMemory.Close();
            }
            catch (WebException e)
            {
                //MessageBox.Show(e.Message + " - " + getRestErrorMessage(response));
                //return null;
                throw e;
            }
            return buffer;
        }

        // 获取异常信息
        private static string getRestErrorMessage(HttpWebResponse errorResponse)
        {
            string errorhtml = getResponseString(errorResponse);
            string errorkey = "spi.UnhandledException:";
            errorhtml = errorhtml.Substring(errorhtml.IndexOf(errorkey) + errorkey.Length);
            errorhtml = errorhtml.Substring(0, errorhtml.IndexOf("\n"));
            return errorhtml;
        }

        // REST @POST 方法
        public static T doPostMethodToObj<T>(string methodUrl, string jsonBody)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "post";
            request.ContentType = RestConst.ContentType_json;
            var stream = request.GetRequestStream();
            using (var writer = new StreamWriter(stream))
            {
                writer.Write(jsonBody);
                writer.Flush();
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string json = getResponseString(response);
            json = json.Replace("@", "");
            return Json.JsonTool.JsonDeserialize<T>(json);
        }

        public static List<T> doPostMethodToObjs<T>(string methodUrl, string jsonBody)
        {
            //jsonBody = "{\"id\":null,\"account\":\"ss\",\"pwd\":\"s\",\"name\":null}";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "post";
            request.ContentType = RestConst.ContentType_json;
            var stream = request.GetRequestStream();
            using (var writer = new StreamWriter(stream))
            {
                writer.Write(jsonBody);
                writer.Flush();
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string json = getResponseString(response);
            json = json.Replace("@", "");
            return Json.JsonTool.JSONStringToList<T>(json);
        }

        public static List<T> doPostMethodToObjs<T>(string methodUrl)
        {
            //jsonBody = "{\"id\":null,\"account\":\"ss\",\"pwd\":\"s\",\"name\":null}";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "post";
            request.ContentType = RestConst.ContentType_json;          
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string json = getResponseString(response);
            json = json.Replace("@", "");
            return Json.JsonTool.JSONStringToList<T>(json);
        }

        public static string doPostRequest(string methodUrl, string jsonBody)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "post";
            request.ContentType = RestConst.ContentType_json;
            var stream = request.GetRequestStream();
            using (var writer = new StreamWriter(stream))
            {
                writer.Write(jsonBody);
                writer.Flush();
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            return getResponseString(response);
        }

        // REST @PUT 方法，带发送内容主体
        public static T doPutMethodToObj<T>(string methodUrl, string jsonBody)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "put";
            request.ContentType = RestConst.ContentType_json;
            var stream = request.GetRequestStream();
            using (var writer = new StreamWriter(stream))
            {
                writer.Write(jsonBody);
                writer.Flush();
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string json = getResponseString(response);
            json = json.Replace("@", "");
            return Json.JsonTool.JsonDeserialize<T>(json);
        }

        // REST @PUT 方法
        public static string doPutMethod(string methodUrl)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "put";
            request.ContentType = RestConst.ContentType_json;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("UTF-8")))
            {
                return reader.ReadToEnd();
            }
        }

        /// <summary>
        ///  REST @PUT 方法 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="methodUrl"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        public static T doPutMethod<T>(string methodUrl, byte[] file)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = "put";
            request.ContentType = RestConst.ContentType_json;
            Stream stream = request.GetRequestStream();
            if (stream.CanWrite)
            {
                stream.Write(file, 0, file.Length);
            }
            stream.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string json = getResponseString(response);
            json = json.Replace("@", "");
            return Json.JsonTool.JsonDeserialize<T>(json);
        }


        // REST @DELETE 方法
        public static string doDeleteMethod(string methodUrl, RestConst.RequestMethod requestMethod = RestConst.RequestMethod.DELETE)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", server_url, methodUrl));
            request.Method = requestMethod.ToString();
            request.ContentType = RestConst.ContentType_json;

            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                //return string.Empty;
                throw e;
            }

            return getResponseString(response);
        }

        //根据实体，反射遍历实体所有属性，动态生成DataTable
        public static DataTable toDataTable(IList list)
        {
            DataTable result = new DataTable();
            if (list.Count > 0)
            {
                FieldInfo[] fieldInfos = list[0].GetType().GetFields();
                foreach (FieldInfo fi in fieldInfos)
                {
                    if (fi.Name.Length > 4 && fi.Name.LastIndexOf("Date") == fi.Name.Length - 4)
                    {
                        result.Columns.Add(fi.Name, "".GetType());
                        continue;
                    }
                    if (fi.Name.Length > 4 && fi.Name.LastIndexOf("Time") == fi.Name.Length - 4)
                    {
                        result.Columns.Add(fi.Name, "".GetType());
                        continue;
                    }
                    if (fi.Name.IndexOf("imagepath") >= 0)
                    {
                        result.Columns.Add(fi.Name, Image.FromFile("1.jpg").GetType());
                        continue;
                    }
                    result.Columns.Add(fi.Name, fi.FieldType);
                }

                for (int i = 0; i < list.Count; i++)
                {
                    ArrayList tempList = new ArrayList();
                    foreach (FieldInfo fi in fieldInfos)
                    {
                        object obj = fi.GetValue(list[i]);
                        if (null == obj)
                        {
                            tempList.Add(obj);
                            continue;
                        }
                        if (fi.Name.Length > 4 && fi.Name.LastIndexOf("Date") == fi.Name.Length - 4)
                        {
                            int dateInt = (int)obj;
                            if (0 == dateInt)
                            {
                                tempList.Add("");
                                continue;
                            }
                            obj = DateTimeUtil.convertIntDatetime(dateInt).ToShortDateString();
                        }
                        if (fi.Name.Length > 4 && fi.Name.LastIndexOf("Time") == fi.Name.Length - 4)
                        {
                            int dateInt = int.Parse(obj.ToString());
                            if (0 == dateInt)
                            {
                                tempList.Add("");
                                continue;
                            }
                            obj = DateTimeUtil.convertIntDatetime(dateInt).ToString();
                        }
                        if (fi.Name.IndexOf("imagepath") >= 0)
                        {
                            if (null == obj)
                            {
                                tempList.Add("");
                                continue;
                            }
                            WebClient myWebClient = new WebClient();
                            MemoryStream ms = new MemoryStream(myWebClient.DownloadData(server_url + obj.ToString()));
                            obj = Image.FromStream(ms);
                        }
                        tempList.Add(obj);
                    }
                    object[] array = tempList.ToArray();
                    result.LoadDataRow(array, true);
                }
            }
            return result;
        }

    }
}
